package edu.ucla.whi.wanda;

import java.util.LinkedList;
import java.util.List;

import org.restlet.ext.wadl.ParameterInfo;
import org.restlet.ext.wadl.ParameterStyle;
import org.restlet.resource.Get;

import com.amazonaws.services.simpledb.model.Item;
import com.amazonaws.services.simpledb.model.SelectRequest;
import com.amazonaws.services.simpledb.model.SelectResult;
import com.amazonaws.util.json.JSONArray;
import com.amazonaws.util.json.JSONException;
import com.amazonaws.util.json.JSONObject;

public abstract class BaseListResource extends BaseResource {
	private String domain;
	private String listKeyName;
	private String listDescription;
	
	public BaseListResource(String domain, String listKeyName, String listDescription) {
		super();
		
		this.domain = domain;
		this.listKeyName = listKeyName;
		this.listDescription = listDescription;
	}

	@Override
	protected List<ParameterInfo> getParams() {
		List<ParameterInfo> params = new LinkedList<ParameterInfo>();
		
		// optional
		params.add(new ParameterInfo("where", false, "xsd:string", ParameterStyle.QUERY, 
				"WHERE condition used in select"));
		params.add(new ParameterInfo("order", false, "xsd:string", ParameterStyle.QUERY, 
				"ORDER BY clause used in select"));
		params.add(new ParameterInfo("next", false, "xsd:string", ParameterStyle.QUERY, 
				"Next token used in select"));
		
		return params;
	}
	
	@Override
	protected List<ParameterInfo> outputParams() {
		List<ParameterInfo> params = new LinkedList<ParameterInfo>();
		
		params.add(newArrayParameterInfo(listKeyName, true, "xsd:string", ParameterStyle.PLAIN, 
				listDescription));
		params.add(new ParameterInfo("query", true, "xsd:string", ParameterStyle.PLAIN, 
				"The query used to generated the list (for debug purpose)"));
		params.add(new ParameterInfo("next", true, "xsd:string", ParameterStyle.PLAIN, 
				"Token for the next page. NULL if reaches the end."));
		
		return params;
	}
	
	public static JSONObject getList(String listKeyName, String domain) {
		return getList(listKeyName, domain, null, null, null);
	}
	
	public static JSONObject getList(String listKeyName, String domain, String where, String order, String next) {
		SelectRequest request = buildSelectRequest(domain, where, order, next, false);

		// Getting subjects
        JSONArray array = new JSONArray();
        SelectResult result = getDB().select(request);
        for (Item item : result.getItems()) {
        	array.put(makeJson(item.getName(), item.getAttributes()));
        }
        
        // Constructing JSON
        JSONObject json = new JSONObject();
        try {
	        json.put(listKeyName, array);
	        json.put("query", request.getSelectExpression());
	        
	        String nextToken = result.getNextToken();
	        json.put("next", nextToken == null ? JSONObject.NULL : nextToken);
        }
        catch (JSONException e) {
        	throw new RuntimeException(e.toString());
        }
        
        return json;
	}
	
	@Get("json")
	public String list() {
		String where = params.get("where");
		String order = params.get("order");
		String next = params.get("next");
		return getList(listKeyName, domain, where, order, next).toString();
	}
}